/*
 * gpio_utils.h
 * 
 * GPIO实用工具函数头文件，包含按键检测和呼吸灯功能的定义
 */

#ifndef GPIO_UTILS_H
#define GPIO_UTILS_H

#include <stdint.h>
#include <unistd.h> // 用于usleep
#include <math.h>   // 用于数学函数和常量

// 包含time.h并确保timespec结构体和CLOCK_MONOTONIC被正确定义
#include <time.h>

// 如果struct timespec未定义，手动定义它
#ifndef HAVE_TIMESPEC
#define HAVE_TIMESPEC
struct timespec {
    time_t tv_sec;  // 秒
    long tv_nsec;   // 纳秒
};
#endif

// 确保定义CLOCK_MONOTONIC
#ifndef CLOCK_MONOTONIC
#define CLOCK_MONOTONIC 1
#endif

// 确保定义数学常量
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923
#endif

// 按键检测相关定义
#define KEY_STATE_IDLE        0     // 空闲状态
#define KEY_STATE_PRESSED     1     // 按下状态
#define KEY_STATE_RELEASED    2     // 释放状态

// 按键事件定义
#define KEY_EVENT_NONE        0     // 无事件
#define KEY_EVENT_SHORT_PRESS 1     // 短按事件
#define KEY_EVENT_LONG_PRESS  2     // 长按事件
#define KEY_EVENT_DOUBLE_CLICK 3    // 双击事件
#define KEY_EVENT_SIX_CLICK   4     // 六击事件

// 按键参数定义 - 为保持兼容性定义两种宏名称
#define SHORT_PRESS_TIME_MS   50    // 短按最小时间（毫秒）
#define LONG_PRESS_TIME_MS    1000  // 长按时间阈值（毫秒）
#define KEY_LONG_PRESS_THRESHOLD_MS LONG_PRESS_TIME_MS // 长按时间阈值（毫秒）
#define CLICK_INTERVAL_MS     300   // 点击间隔时间阈值（毫秒）
#define KEY_CLICK_INTERVAL_MS CLICK_INTERVAL_MS // 点击间隔时间阈值（毫秒）
#define DEBOUNCE_TIME_MS      20    // 去抖动时间（毫秒）

// 呼吸灯效果定义
typedef enum {
    BREATH_EFFECT_SLOW = 0,    // 平缓呼吸效果
    BREATH_EFFECT_FAST,        // 急促呼吸效果
    BREATH_EFFECT_PULSE,       // 脉冲效果
    BREATH_EFFECT_WAVE         // 波浪效果
} breath_effect_t;

// 呼吸灯参数定义
#define BREATH_CYCLE_SLOW      2000  // 平缓呼吸周期（毫秒）
#define BREATH_CYCLE_FAST       500  // 急促呼吸周期（毫秒）
#define BREATH_CYCLE_PULSE      300  // 脉冲周期（毫秒）
#define BREATH_CYCLE_WAVE      3000  // 波浪周期（毫秒）

// 按键状态结构体
typedef struct {
    int gpio_num;               // GPIO引脚号
    uint8_t state;              // 当前按键状态
    uint8_t prev_state;         // 上一次按键状态
    uint32_t press_start_time;  // 按下开始时间
    uint32_t release_time;      // 释放时间
    uint8_t click_count;        // 点击计数
} key_state_t;

// GPIO操作函数声明
extern int gpio_get_value(int gpio, int *value);
extern int gpio_set_value(int gpio, int value);
extern int gpio_init(int gpio, const char *direction);
extern int gpio_cleanup(int gpio);

// 函数声明

/**
 * 获取系统当前时间（毫秒）
 * 
 * 返回值: 当前系统时间（毫秒）
 */
uint32_t get_system_time_ms(void);

/**
 * 初始化按键状态
 * 
 * @param key_state: 按键状态结构体指针
 * @param gpio_num: GPIO引脚号
 */
void key_init(key_state_t *key_state, int gpio_num);

/**
 * 按键状态检测
 * 
 * @param key_state: 按键状态结构体指针
 * 
 * 返回值: 检测到的按键事件
 */
uint8_t key_detect(key_state_t *key_state);

/**
 * 设置LED亮度
 * 
 * @param gpio_num: GPIO引脚号
 * @param brightness: 亮度值（0-255）
 * 
 * 返回值: 成功返回0，失败返回-1
 */
int led_set_brightness(int gpio_num, uint8_t brightness);

/**
 * 实现呼吸灯效果
 * 
 * @param gpio_num: GPIO引脚号
 * @param effect: 呼吸灯效果类型
 * @param duration_ms: 持续时间（毫秒）
 * 
 * 返回值: 成功返回0，失败返回-1
 */
int led_breath(int gpio_num, breath_effect_t effect, uint32_t duration_ms);

#endif // GPIO_UTILS_H